package com.meiyuetao.myt.stock.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import lab.s2jh.auth.security.AuthUserHolder;
import lab.s2jh.core.dao.BaseDao;
import lab.s2jh.core.service.BaseService;
import lab.s2jh.core.service.Validation;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.meiyuetao.myt.core.constant.VoucherStateEnum;
import com.meiyuetao.myt.core.constant.VoucherTypeEnum;
import com.meiyuetao.myt.md.dao.CommodityDao;
import com.meiyuetao.myt.md.entity.Commodity;
import com.meiyuetao.myt.stock.dao.CommodityStockDao;
import com.meiyuetao.myt.stock.dao.CommodityStockMoveDao;
import com.meiyuetao.myt.stock.dao.StockInOutDao;
import com.meiyuetao.myt.stock.dao.StorageLocationDao;
import com.meiyuetao.myt.stock.entity.CommodityStock;
import com.meiyuetao.myt.stock.entity.CommodityStockMove;
import com.meiyuetao.myt.stock.entity.CommodityStockMoveDetail;
import com.meiyuetao.myt.stock.entity.StockInOut;
import com.meiyuetao.myt.stock.entity.StorageLocation;

@Service
@Transactional
public class CommodityStockMoveService extends BaseService<CommodityStockMove, Long> {
    @Autowired
    private CommodityStockMoveDao commodityStockMoveDao;
    @Autowired
    private CommodityStockService commodityStockService;
    @Autowired
    private CommodityStockDao commodityStockDao;
    @Autowired
    private CommodityDao commodityDao;
    @Autowired
    private StorageLocationDao storageLocationDao;
    @Autowired
    private StockInOutDao stockInOutDao;
    @Autowired
    private StockInOutService stockInOutService;

    @Override
    protected BaseDao<CommodityStockMove, Long> getEntityDao() {
        return commodityStockMoveDao;
    }

    @Override
    public CommodityStockMove save(CommodityStockMove entity) {
        return commodityStockMoveDao.save(entity);
    }

    public CommodityStockMove post(CommodityStockMove entity) {
        StorageLocation originStorageLocation = storageLocationDao.findOne(entity.getOriginStorageLocation().getId());
        StorageLocation destinationStorageLocation = storageLocationDao.findOne(entity.getDestinationStorageLocation().getId());
        for (CommodityStockMoveDetail csmd : entity.getCommodityStockMoveDetails()) {
            Commodity commodity = commodityDao.findOne(csmd.getCommodity().getId());
            String batchNo = csmd.getBatchNo();
            CommodityStock commodityStockOrigin = commodityStockService.findBy(commodity, originStorageLocation, batchNo);
            Validation.isTrue(commodityStockOrigin != null, "须先初始化维护库存数据: 商品=[" + commodity.getDisplay() + "],库存地=[" + originStorageLocation.getDisplay() + "],批次号=[" + batchNo
                    + "]");
            StockInOut stockInOut = new StockInOut(entity.getVoucher(), null, VoucherTypeEnum.DH, commodityStockOrigin);
            stockInOut.setDiffQuantity(csmd.getQuantity().negate());
            stockInOut.setDiffStockAmount(commodityStockOrigin.getCostPrice().multiply(csmd.getQuantity().negate()));
            stockInOut.setOperationSummary("调货单，扣减源实际库存量");
            stockInOutService.saveCascade(stockInOut);

            CommodityStock commodityStockDestination = commodityStockService.findBy(commodity, destinationStorageLocation, batchNo);
            if (commodityStockDestination == null) {
                commodityStockDestination = new CommodityStock();
                commodityStockDestination.setCommodity(commodity);
                commodityStockDestination.setStorageLocation(destinationStorageLocation);
                commodityStockDestination.setBatchNo(batchNo);
                commodityStockDestination.setExpireDate(csmd.getExpireDate());

            }
            StockInOut stockInOut2 = new StockInOut(entity.getVoucher(), null, VoucherTypeEnum.DH, commodityStockDestination);
            stockInOut2.setDiffPurchasingQuantity(csmd.getQuantity());
            stockInOut2.setOperationSummary("调货单，增加目的在途量");
            stockInOutService.saveCascade(stockInOut2);
        }
        return super.save(entity);
    }

    public void chargeAgainst(CommodityStockMove bindingEntity) {
        CommodityStockMove commodityStockMove = new CommodityStockMove();
        BeanUtils.copyProperties(bindingEntity, commodityStockMove, new String[] { "id", "commodityStockMoveDetails", "createdBy", "createdDt", "updatedBy", "updatedDt",
                "version", "voucher", "voucherDate", "voucherState", "totalDeliveryAmount", "totalCostAmount" });
        commodityStockMove.setVoucherDate(new Date());
        if (AuthUserHolder.getLogonUser().getDepartment() == null) {
            commodityStockMove.setVoucherDepartment(bindingEntity.getVoucherDepartment());
        } else {
            commodityStockMove.setVoucherDepartment(AuthUserHolder.getLogonUser().getDepartment());
        }

        String voucher = "R" + bindingEntity.getVoucher();
        commodityStockMove.setVoucher(voucher);
        bindingEntity.setVoucherState(VoucherStateEnum.REDW);
        commodityStockMove.setVoucherState(VoucherStateEnum.REDW);

        commodityStockMove.setTotalCostAmount(bindingEntity.getTotalCostAmount() == null ? null : bindingEntity.getTotalCostAmount().negate());
        commodityStockMove.setTotalDeliveryAmount(bindingEntity.getTotalDeliveryAmount() == null ? null : bindingEntity.getTotalDeliveryAmount().negate());
        List<CommodityStockMoveDetail> commodityStockMoveDetails = new ArrayList<CommodityStockMoveDetail>();
        for (CommodityStockMoveDetail csmd : bindingEntity.getCommodityStockMoveDetails()) {
            CommodityStockMoveDetail commodityStockMoveDetail = new CommodityStockMoveDetail();
            BeanUtils.copyProperties(csmd, commodityStockMoveDetail, new String[] { "id", "createdBy", "createdDt", "updatedBy", "updatedDt", "version", "commodityStockMove",
                    "quantity", "inStockQuantity", "amount", "costAmount", "deliveryAmount" });
            commodityStockMoveDetail.setCommodityStockMove(commodityStockMove);
            commodityStockMoveDetail.setQuantity(csmd.getQuantity().negate());
            commodityStockMoveDetail.setInStockQuantity(csmd.getInStockQuantity().negate());
            commodityStockMoveDetail.setAmount(csmd.getAmount().negate());
            commodityStockMoveDetail.setCostAmount(csmd.getCostAmount().negate());
            commodityStockMoveDetail.setDeliveryAmount(csmd.getDeliveryAmount());
            commodityStockMoveDetails.add(commodityStockMoveDetail);
        }
        commodityStockMove.setCommodityStockMoveDetails(commodityStockMoveDetails);
        this.post(commodityStockMove);
        // saleDeliveryDao.save(saleDelivery);
        commodityStockMoveDao.save(bindingEntity);
    }

}
